<script setup lang="ts">
import type { ZhuMember } from '../../../types/zhu-family';

import { onBeforeUnmount, onMounted, ref } from 'vue';

import { PlusOutlined } from '@ant-design/icons-vue';
import G6 from '@antv/g6';
import { message } from 'ant-design-vue';

import { buildFamilyTree, zhuMembers } from '../../../mock/zhu-dynasty/members';
import MemberDetailPanel from './components/MemberDetailPanel.vue';

const graphContainer = ref<HTMLDivElement>();
const layoutMode = ref('TB');
const drawerVisible = ref(false);
const selectedMember = ref<null | ZhuMember>(null);

let graph: G6.TreeGraph;

onMounted(() => {
  initGraph();
  loadData();

  window.addEventListener('resize', handleResize);
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize);
  graph?.destroy();
});

function initGraph() {
  // 注册自定义节点
  G6.registerNode(
    'member-card',
    {
      draw(cfg: any, group: any) {
        const width = 180;
        const height = 90;

        // 背景卡片
        const rect = group!.addShape('rect', {
          attrs: {
            x: -width / 2,
            y: -height / 2,
            width,
            height,
            radius: 8,
            fill:
              cfg.role === 'emperor'
                ? '#fff7e6'
                : cfg.hasSBT
                  ? '#e6f7ff'
                  : '#fafafa',
            stroke:
              cfg.role === 'emperor'
                ? '#faad14'
                : cfg.hasSBT
                  ? '#1890ff'
                  : '#d9d9d9',
            lineWidth: 2,
            cursor: 'pointer',
          },
          name: 'rect-shape',
        });

        // 头像
        group!.addShape('image', {
          attrs: {
            x: -width / 2 + 10,
            y: -height / 2 + 15,
            width: 50,
            height: 50,
            img: cfg.avatar,
            borderRadius: 25,
          },
          name: 'avatar',
        });

        // 姓名
        group!.addShape('text', {
          attrs: {
            x: -width / 2 + 70,
            y: -height / 2 + 28,
            text: cfg.name,
            fontSize: 14,
            fontWeight: 'bold',
            fill: '#000',
          },
          name: 'name',
        });

        // 封号/谥号
        group!.addShape('text', {
          attrs: {
            x: -width / 2 + 70,
            y: -height / 2 + 48,
            text:
              cfg.title.length > 10
                ? `${cfg.title.slice(0, 10)}...`
                : cfg.title,
            fontSize: 12,
            fill: '#666',
          },
          name: 'title',
        });

        // 第几代
        group!.addShape('text', {
          attrs: {
            x: -width / 2 + 70,
            y: -height / 2 + 68,
            text: `第${cfg.generation}代 · ${cfg.role === 'emperor' ? '皇帝' : cfg.role === 'prince' ? '藩王' : '宗室'}`,
            fontSize: 11,
            fill: '#999',
          },
          name: 'generation',
        });

        // SBT 徽章
        if (cfg.hasSBT) {
          group!.addShape('circle', {
            attrs: {
              x: width / 2 - 18,
              y: -height / 2 + 18,
              r: 14,
              fill: '#52c41a',
            },
          });

          group!.addShape('text', {
            attrs: {
              x: width / 2 - 18,
              y: -height / 2 + 18,
              text: '✓',
              fontSize: 16,
              fill: '#fff',
              textAlign: 'center',
              textBaseline: 'middle',
            },
          });
        }

        // 皇帝标识
        if (cfg.role === 'emperor') {
          group!.addShape('text', {
            attrs: {
              x: width / 2 - 18,
              y: height / 2 - 18,
              text: '帝',
              fontSize: 14,
              fill: '#faad14',
              fontWeight: 'bold',
            },
          });
        }

        return rect;
      },
    },
    'single-node',
  );

  // 创建 G6 图实例
  graph = new G6.TreeGraph({
    container: graphContainer.value!,
    width: graphContainer.value!.clientWidth,
    height: 800,
    modes: {
      default: ['drag-canvas', 'zoom-canvas'],
    },
    defaultNode: {
      type: 'member-card',
    },
    defaultEdge: {
      type: 'cubic-vertical',
      style: {
        stroke: '#b8860b',
        lineWidth: 2,
      },
    },
    layout: {
      type: 'compactBox',
      direction: layoutMode.value,
      getId: (d: any) => d.id,
      getHeight: () => 90,
      getWidth: () => 180,
      getVGap: () => 50,
      getHGap: () => 80,
    },
    animate: true,
  });

  // 点击节点事件
  graph.on('node:click', (e) => {
    const model = e.item!.getModel();
    const member = zhuMembers.find((m) => m.id === model.id);
    if (member) {
      selectedMember.value = member;
      drawerVisible.value = true;
    }
  });

  // 鼠标悬停效果
  graph.on('node:mouseenter', (e) => {
    graph.setItemState(e.item!, 'hover', true);
  });

  graph.on('node:mouseleave', (e) => {
    graph.setItemState(e.item!, 'hover', false);
  });
}

function loadData() {
  const treeData = buildFamilyTree(zhuMembers);
  graph.data(treeData);
  graph.render();
  graph.fitView();
}

function changeLayout() {
  const layouts: any = {
    TB: { type: 'compactBox', direction: 'TB' },
    LR: { type: 'compactBox', direction: 'LR' },
    radial: { type: 'dendrogram', radial: true },
  };

  graph.updateLayout(layouts[layoutMode.value]);
}

function handleResize() {
  if (!graph || graph.get('destroyed')) return;
  const width = graphContainer.value!.clientWidth;
  graph.changeSize(width, 800);
  graph.fitView();
}

function handleUpdateMember(member: ZhuMember) {
  message.success('成员信息已更新！（Mock 模式）');
}

function handleMintSBT(member: ZhuMember) {
  message.loading(`正在为 ${member.name} 铸造 SBT...`, 2);

  // 模拟铸造延迟
  setTimeout(() => {
    member.hasSBT = true;
    member.sbtTokenId = Math.floor(Math.random() * 9000) + 1000;
    graph.updateItem(member.id, member);
    message.success('SBT 铸造成功！');
  }, 2000);
}
</script>

<template>
  <div class="genealogy-page">
    <a-card>
      <template #title>
        <div class="page-header">
          <span>🌳 朱氏皇族世系图</span>
          <div class="header-actions">
            <a-radio-group
              v-model:value="layoutMode"
              button-style="solid"
              @change="changeLayout"
            >
              <a-radio-button value="TB">纵向树图</a-radio-button>
              <a-radio-button value="LR">横向树图</a-radio-button>
              <a-radio-button value="radial">环状图</a-radio-button>
            </a-radio-group>

            <a-button type="primary"> <PlusOutlined /> 添加成员 </a-button>
          </div>
        </div>
      </template>

      <div ref="graphContainer" class="graph-container"></div>
    </a-card>

    <!-- 成员详情抽屉 -->
    <a-drawer
      v-model:open="drawerVisible"
      title="成员详情"
      width="500"
      placement="right"
    >
      <MemberDetailPanel
        v-if="selectedMember"
        :member="selectedMember"
        @update="handleUpdateMember"
        @mint-sbt="handleMintSBT"
      />
    </a-drawer>
  </div>
</template>

<style scoped lang="scss">
.genealogy-page {
  .page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
  }

  .header-actions {
    display: flex;
    gap: 12px;
  }

  .graph-container {
    width: 100%;
    height: 800px;
    background: linear-gradient(180deg, #fff8e1 0%, #fff 100%);
    border: 1px solid #f0f0f0;
    border-radius: 4px;
  }
}
</style>
